package com.wanfu.aop;

import com.wanfu.annotation.Log;
import com.wanfu.service.LogService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;

@Slf4j
@Aspect
@Configuration
public class LogAspect {
    @Resource
    private LogService logService;

    @Pointcut("execution(* com.wanfu.service.*.*(..))")
    public void serviceLog(){}

    @Before("serviceLog()")
    public void serviceLogBefore(JoinPoint point){
        log.info("startService -- " + point.getTarget().getClass().getName() + " --> method: " + point.getSignature().getName());
    }

    @AfterReturning("serviceLog()")
    public void serviceLogAfterReturning(JoinPoint point) throws ClassNotFoundException {
        /*try {
            Subject subject = null ;
            try {
                subject = CarfiUserUtil.getSubject();
            } catch (Exception e) {
                e.printStackTrace();
                //发生异常则不进行
                return ;
        }*/
        com.wanfu.entity.Log logEntity = new com.wanfu.entity.Log();
        String targetName = point.getTarget().getClass().getName();
        Class targetClass = Class.forName(targetName);
        String methodName = point.getSignature().getName();
        Method[] methods = targetClass.getMethods();
        Object[] params = point.getArgs(); // 获得参数列表
        point.getSignature().getDeclaringType().getAnnotation(Log.class);

        for (Method method : methods) {
            //  定位到类下指定的方法
            if (method.getName().equals(methodName) && method.getParameterCount() == params.length) {
                //Class[] tempClass = method.getParameterTypes();
                //  筛选出重载的方法
                //if (tempClass.length == params.length) {
                    //  获取注解内容
                    Log logAnnotation = method.getAnnotation(Log.class);
                    if (logAnnotation != null) {
                        logEntity.setModuleName(logAnnotation.moduleName());
                        logEntity.setOpType(StringUtils.isEmpty(logAnnotation.value()) ? logAnnotation.opType() : logAnnotation.value());
                        logEntity.setContent(logAnnotation.content());
                        logService.addLog(logEntity);
                        break;
                    }
                //}
            }
        }
        log.info("endService -- " + targetName + " --> method: " + methodName);
    }

    @Pointcut("execution(* com.wanfu.controller.*.*(..))")
    public void controllerLog(){}

    @Before("controllerLog()")
    public void controllerLogBefore(JoinPoint point){
        // 接收到请求，记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        log.info("startController -- path : " + request.getRequestURI() + " --> params: " + Arrays.toString(point.getArgs()));
    }

    @AfterReturning("controllerLog()")
    public void controllerLogAfterReturning() throws ClassNotFoundException {
        log.info("endController -- ");
    }
}
